﻿/*
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
 *
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
 *
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
 */

#include "JT1078Rtp.h"
#include "JT1078.h"
#include "Factory.h"

namespace mediakit {

void JT1078RtpDecoder::flushFrame(uint64_t stamp_ms) {
    _drop = true;
    auto buffer = std::make_shared<toolkit::BufferString>(std::move(_content));
    auto frame = Factory::getFrameFromBuffer(_codec_id, std::move(buffer), stamp_ms, stamp_ms);
    inputFrame(frame);
}

bool JT1078RtpDecoder::inputRtp(const RtpPacket::Ptr &packet, bool) {
    auto rtp = packet->getHeader();
    auto type = (JT1078FrameType)rtp->frame_type;
    // jt1078 csrc固定为1，不适用于 RtpPacket::getPayloadData()
    auto payload = (JT1078Payload *)rtp->payload;
    auto content_ptr = (const char *)payload->data(type);
    auto content_size = payload->size(type);
    switch ((JT1078SliceType)rtp->slice_type) {
        case JT1078SliceType::ATOMIC: {
            _content.assign(content_ptr, content_size);
            flushFrame(payload->getStampMS(type));
            break;
        }

        case JT1078SliceType::BEGIN: {
            _content.assign(content_ptr, content_size);
            _last_seq = packet->getSeq();
            _drop = false;
            break;
        }

        case JT1078SliceType::END:
        case JT1078SliceType::MIDDLE: {
            if (_drop) {
                return false;
            }
            auto seq = packet->getSeq();
            if ((uint16_t)(_last_seq + 1) != seq) {
                WarnL << "seq dropped:" << _last_seq << "+1 != " << seq;
                _drop = true;
                break;
            }
            _content.append(content_ptr, content_size);
            _last_seq = seq;
            if ((JT1078SliceType)rtp->slice_type == JT1078SliceType::END) {
                flushFrame(payload->getStampMS(type));
            }
            break;
        }

        default: break;
    }
    return true;
}

} // namespace mediakit